#pragma once
#include"../comm/log.hpp"
#include<iostream>
#include<string>
#include<assert.h>
#include<vector>
#include<fstream>
#include<cstdlib>
#include"../comm/util.hpp"
#include<unordered_map>
//根据list,加载所有题目信息
//用于数据交互，对外提供访问接口
namespace ns_model
{
    using namespace ns_log;
    using namespace std;
    using namespace ns_util;
    //题目内容详情
    struct Question
    {
        std::string number;
        std::string title;
        std::string star;
        int cpu_limt;
        int mem_limt;
        std::string desc;
        std::string header;
        std::string tail;
    };
    //给出题目列表路径，便于获取所有题目基本信息
    const std::string question_list="./questions/questions.list";
    //给出主路径，便于查找单一目的题目信息
    std::string path="./questions/";
    class Model
    {
    public:
    Model()
    {
        //加载内容
        assert(LoadQuestionList(question_list));
    }
    ~Model()
    {}
    //获取列表文件资源
    bool LoadQuestionList(const std::string &question_list)
    {
        ifstream in(question_list);
        if(!in.is_open())
        {
            LOG(FATAL)<<"打开配置文件失败"<<"\n";
            return false;
        }
        string line;
        while(getline(in,line))
        {
            vector<string>tmp;
            //对当行数据进行分割
            StringUtill::SplitSpring(line,&tmp," ");
            if(tmp.size()==0)
            {
                LOG(WARNING)<<"加载题目失败"<<"\n";
                continue;
            }
            Question q;
            
            q.number=tmp[0];
            q.title=tmp[1];
            q.star=tmp[2];
            q.cpu_limt=atoi(tmp[3].c_str());
            q.mem_limt=atoi(tmp[4].c_str());
            std::string aim_path=path+q.number;
            aim_path+="/";
            FileUtil::ReadFile(aim_path+"desc.txt",&(q.desc),true);
            FileUtil::ReadFile(aim_path+"header.hpp",&(q.header),true);
            FileUtil::ReadFile(aim_path+"tail.cpp",&(q.tail),true);
            questions.insert({q.number,q});
        }
        LOG(INFO)<<"题目加载成功"<<"\n";
        in.close();
        return true;
    }

    bool GetAllQuestions(vector<Question>*out)
    {
        if(questions.size()==0)
        {
            LOG(ERROR)<<"获取所有题目失败"<<"\n";
            return false;
        }
        for(auto &e:questions)
        {
            out->push_back(e.second);
        }
        return true;
    }
    bool GetOneQuestions(const std::string &number,Question*q)
    {
        const auto&iter=questions.find(number);
        if(iter==questions.end())
        {
            LOG(ERROR)<<"获取题目失败"<<"\n";
            return false;
        }
        (*q)=iter->second;
        return true;
    }
    private:
        unordered_map<string,Question>questions;
    };
}
